<?php


namespace app\common\think\log\driver;

use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use think\App;
use think\contract\LogHandlerInterface;


/**
 * Created by PhpStorm
 * USER zhangkai QQ 920062039
 * Date 2022/7/29   11:33
 */
class Monolog implements LogHandlerInterface
{

    /**
     * 配置参数
     * @var array
     */
    protected $config = [
        'time_format'  => 'c',
        'single'       => false,
        'apart_level'  => [],
        'json'         => false,
        'json_options' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
        'format'       => '[%s][%s] %s',
    ];

    /**
     * @var Logger
     */
    private $handler = null;

    // 实例化并传入参数
    public function __construct(App $app, $config = [])
    {

        if (is_array($config)) {
            $this->config = array_merge($this->config, $config);
        }

        if (empty($this->config['format'])) {
            $this->config['format'] = '[%s][%s] %s';
        }

        if (empty($this->config['allow_inline_lineBreaks'])) {
            $this->config['allow_inline_lineBreaks'] = true;
        }

        $this->handler = new Logger('stdout');
//        monolog 内置，用不到，同化成thinkphp的格式
//        $dateFormat = "Y n j, g:i a";
//        $output = "%datetime% > %level_name% > %message% %context% %extra%\r\n";
        $output = "%message%";
        $formatter = new LineFormatter($output, null,$this->config['allow_inline_lineBreaks']);
        $stream = new StreamHandler('php://stdout', Logger::DEBUG);
        $stream->setFormatter($formatter);
        $this->handler->pushHandler($stream);


    }


//    public function save(array $log): bool
//    {
//        foreach ($log as $key => $value){
//            $content = $key." : ";
//            foreach ($value as $logItem){
//                $content .= var_export($logItem,true);
//            }
//            $this->handler->debug($content);
//        }
//        return true;
//    }

    public function save(array $log): bool
    {
        $info = [];

        // 日志信息封装
        $time = \DateTime::createFromFormat('0.u00 U', microtime())->setTimezone(new \DateTimeZone(date_default_timezone_get()))->format($this->config['time_format']);

        foreach ($log as $type => $val) {
            $message = [];
            foreach ($val as $msg) {
                if (!is_string($msg)) {
                    $msg = var_export($msg, true);
                }

                $message[] = $this->config['json'] ?
                    json_encode(['time' => $time, 'type' => $type, 'msg' => $msg], $this->config['json_options']) :
                    sprintf($this->config['format'], $time, $type, $msg);
            }

            $info[$type] = $message;
        }

        if ($info) {
            // 文件也需要记录
            return $this->write($info);
        }

        return true;
    }

    /**
     * 日志写入
     * @access protected
     * @param array  $message     日志信息
     * @return bool
     */
    protected function write(array $message): bool
    {
        $info = [];

        foreach ($message as $type => $msg) {
            $info[$type] = is_array($msg) ? implode(PHP_EOL, $msg) : $msg;
        }

        $message = implode(PHP_EOL, $info) . PHP_EOL;

        $this->handler->debug($message);
        app()->log->channel('file')->write($message);

        return true;
    }
}